package cn.midas.user.service.impl;

import cn.midas.basic.constant.BaseConstants;
import cn.midas.basic.dto.RejisterDto;
import cn.midas.basic.exception.BusinessException;
import cn.midas.basic.utils.MD5Utils;
import cn.midas.basic.utils.StrUtils;
import cn.midas.user.domain.Logininfo;
import cn.midas.user.domain.User;
import cn.midas.user.mapper.LogininfoMapper;
import cn.midas.user.mapper.UserMapper;
import cn.midas.user.service.IUserService;
import cn.midas.basic.service.impl.BaseServiceImpl;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author zt
 * @since 2022-07-06
 */
@Service
public class UserServiceImpl extends BaseServiceImpl<User> implements IUserService {

    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private LogininfoMapper logininfoMapper;
    @Override
    public void registerPhone(RejisterDto rejisterDto) {
        String phoneCodeValue = rejisterDto.getPhoneCodeValue();
        String phone = rejisterDto.getPhone();
        String password = rejisterDto.getPassword();
        String confirmPassword = rejisterDto.getConfirmPassword();
        //1.参数为空校验
        if (StringUtils.isEmpty(rejisterDto.getConfirmPassword())){
            throw new BusinessException("第二次密码不能为空！");
        }
        if (StringUtils.isEmpty(rejisterDto.getPassword())){
            throw new BusinessException("第一次密码不能为空！");
        }
        if (StringUtils.isEmpty(rejisterDto.getPhone())){
            throw new BusinessException("手机号不能为空！");
        }
        //2.两次密码是否一致
        if (!rejisterDto.getPassword().equals(rejisterDto.getConfirmPassword())){
            throw new BusinessException("两次密码填写不一致，请重新填写！");
        }
        //3.注册时手机号码与获取验证码手机号码是否一致
        String phoneCodeKey = BaseConstants.GraphCodeConstants.BUSINESS_LOGIN_KEY + phone;
        Object phoneCodeValueRedis = redisTemplate.opsForValue().get(phoneCodeKey);
         if (phoneCodeValueRedis == null){
             throw new BusinessException("验证码已经过期，请重新填写！");
         }
        //4.判断手机验证码是否一致
        //4.1获取redis中验证码
        String[] split = phoneCodeValueRedis.toString().split(":");
         String phoneCode = split[0];
         if (!phoneCode.equalsIgnoreCase(phoneCodeValue)){
             throw new BusinessException("验证码不正确，请重新填写！");
         }

        //5.判断用户是否已注册，如果已注册提示用户
        User user = userMapper.loadByPhone(phone);
        if (user != null){
            throw new BusinessException("用户已注册，请直接登录，如果忘记密码，请点击忘记密码！");
        }
        //6.保存user表和logininfo表
        //6.1 将rejisterDto的数据拷贝到user表中
        user = rejister2User(rejisterDto);
        userMapper.save(user);
        //6.1 将user的数据拷贝到logininfo表中
        Logininfo logininfo = user2Logininfo(user);
        logininfoMapper.save(logininfo);
       // 将表logininfo主键id设置到user表
        user.setLogininfoId(logininfo.getId());
        userMapper.update(user);
    }

    /**
    * @Title: user2Logininfo
    * @Description: 使用工具类将user拷贝到logininfo
    * @Author: Mr.She
    * @Version: 1.0
    * @Date:  2022/7/6 18:28
    * @Parameters: [user]
    * @Return cn.midas.user.domain.Logininfo
    */
    private Logininfo user2Logininfo(User user) {
        Logininfo logininfo = new Logininfo();
        // 使用工具类BeanUtils将user拷贝到logininfo
        BeanUtils.copyProperties(user,logininfo);
        // 设置type字段为1
        logininfo.setType(1);
        return logininfo;
    }

    /*/**
    * @Title: rejister2User
    * @Description: 将rejisterDto的值赋值给user
    * @Author: Mr.She
    * @Version: 1.0
    * @Date:  2022/7/6 18:29
    * @Parameters: [rejisterDto]
    * @Return cn.midas.user.domain.User
    */
    private User rejister2User(RejisterDto rejisterDto) {
        User user = new User();
        String phone = rejisterDto.getPhone();
        user.setPhone(phone);
        user.setUsername(phone);
        // 拿到盐值
        String salt = StrUtils.getComplexRandomString(32);
        // 使用md5进行加盐加密
        String saltPassword = MD5Utils.encrypByMd5(rejisterDto.getPassword() + salt);
        user.setSalt(salt);
        user.setPassword(saltPassword);
        return user;
    }

    @Override
    public void save(User user) {
        //初始化user
        initUser(user);
        //使用工具类见user拷贝到logininfo中
        Logininfo logininfo = user2Logininfo(user);
        userMapper.save(user);
        logininfoMapper.save(logininfo);
        user.setLogininfoId(logininfo.getId());
        userMapper.update(user);

    }

    @Override
    public void remove(Long id) {
        userMapper.remove(id);
        User user = userMapper.loadById(id);
        Long logininfoId = user.getLogininfoId();
        logininfoMapper.remove(logininfoId);
    }

    @Override
    public void batchDel(Long[] ids) {
        userMapper.batchDel(ids);
        for (Long id : ids) {
            User user = userMapper.loadById(id);
            Long logininfoId = user.getLogininfoId();
            logininfoMapper.remove(logininfoId);
        }
    }

    @Override
    public void update(User user) {
        initUser(user);
        userMapper.update(user);
        Logininfo logininfo = user2Logininfo(user);
        logininfoMapper.update(logininfo);
    }

    private void initUser(User user) {
        // 盐值
        String salt = StrUtils.getComplexRandomString(32);
        // 加盐加密
        String saltPassword = MD5Utils.encrypByMd5(user.getPassword() + salt);
        user.setSalt(salt);
        user.setPassword(saltPassword);
    }
}
